home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 February / PCWorld_2006-02_cd.bin / software / vyzkuste / triky / triky.exe / httrack-3.33.exe / {app} / src / htswizard.c < prev    next >
C/C++ Source or Header  |  2004-05-09  |  34KB  |  934 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       wizard system (accept/refuse links)                    */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. /* Internal engine bytecode */
  39. #define HTS_INTERNAL_BYTECODE
  40.  
  41. #include "htswizard.h"
  42. #include "htsdefines.h"
  43.  
  44. /* specific definitions */
  45. #include "htsbase.h"
  46. #include <ctype.h>
  47. /* END specific definitions */
  48.  
  49. // version 1 pour httpmirror
  50. // flusher si on doit lire peu α peu le fichier
  51. #define test_flush if (opt->flush) { fflush(opt->log); fflush(opt->errlog); }
  52.  
  53. // pour allΘger la syntaxe, des raccourcis sont crΘΘs
  54. #define urladr   (liens[ptr]->adr)
  55. #define urlfil   (liens[ptr]->fil)
  56.  
  57. // libΘrer filters[0] pour insΘrer un ΘlΘment dans filters[0]
  58. #define HT_INSERT_FILTERS0 do {\
  59.   int i;\
  60.   if (*opt->filters.filptr > 0) {\
  61.     for(i = (*opt->filters.filptr)-1 ; i>=0 ; i--) {\
  62.       strcpybuff((*opt->filters.filters)[i+1],(*opt->filters.filters)[i]);\
  63.     }\
  64.   }\
  65.   (*opt->filters.filters)[0][0]='\0';\
  66.   (*opt->filters.filptr)++;\
  67.   assertf((*opt->filters.filptr) < opt->maxfilter); \
  68. } while(0)
  69.  
  70.  
  71.  
  72. /*
  73. httrackp opt     bloc d'options
  74. int ptr,int lien_tot,lien_url** liens
  75.                              relatif aux liens
  76. char* adr,char* fil
  77.                              adresse/fichier α tester
  78. char** filters,int filptr,int filter_max
  79.                              relatif aux filtres
  80. robots_wizard* robots
  81.                              relatif aux robots
  82. int* set_prio_to
  83.                              callback obligatoire "capturer ce lien avec prio=N-1"
  84. int* just_test_it
  85.                              callback optionnel "ne faire que tester ce lien Θventuellement"
  86. retour:
  87.                0 acceptΘ
  88.                1 refusΘ
  89.                -1 pas d'avis
  90. */
  91. int hts_acceptlink(httrackp* opt,
  92.                    int ptr,int lien_tot,lien_url** liens,
  93.                    char* adr,char* fil,
  94.                    char* tag, char* attribute,
  95.                    int* set_prio_to,
  96.                    int* just_test_it) {
  97.   
  98.   int forbidden_url=-1;
  99.   int meme_adresse;
  100. #define _FILTERS     (*opt->filters.filters)
  101. #define _FILTERS_PTR (opt->filters.filptr)
  102. #define _ROBOTS      ((robots_wizard*)opt->robotsptr)
  103.   int may_set_prio_to=0;
  104.  
  105.   // -------------------- PHASE 0 --------------------
  106.  
  107.   /* Infos */
  108.   if ((opt->debug>1) && (opt->log!=NULL)) {
  109.     fspc(opt->log,"debug"); fprintf(opt->log,"wizard test begins: %s%s"LF,adr,fil);
  110.     test_flush;
  111.   }
  112.   
  113.   /* Already exists? Then, we know that we knew that this link had to be known */
  114.   if (adr[0] != '\0'
  115.     && fil[0] != '\0'
  116.     && opt->hash != NULL
  117.     && hash_read((hash_struct*)opt->hash, adr, fil, 1, opt->urlhack) >= 0
  118.     ) {
  119.     return 0;  /* Yokai */
  120.   }
  121.   
  122.   // -------------------- PHASE 1 --------------------
  123.  
  124.   /* Doit-on traiter les non html? */
  125.   if ((opt->getmode & 2)==0) {    // non on ne doit pas
  126.     if (!ishtml(fil)) {  // non il ne faut pas
  127.       //adr[0]='\0';    // ne pas traiter ce lien, pas traiter
  128.       forbidden_url=1;    // interdire rΘcupΘration du lien
  129.       if ((opt->debug>1) && (opt->log!=NULL)) {
  130.         fspc(opt->log,"debug"); fprintf(opt->log,"non-html file ignored at %s : %s"LF,adr,fil);
  131.         test_flush;
  132.       }
  133.       
  134.     }
  135.   }
  136.   
  137.   /* Niveau 1: ne pas parser suivant! */
  138.   if (ptr>0) {
  139.     if (liens[ptr]->depth <= 1) {
  140.       forbidden_url=1;    // interdire rΘcupΘration du lien
  141.       if ((opt->debug>1) && (opt->log!=NULL)) {
  142.         fspc(opt->log,"debug"); fprintf(opt->log,"file from too far level ignored at %s : %s"LF,adr,fil);
  143.         test_flush;
  144.       }
  145.     }
  146.   }
  147.  
  148.   /* en cas d'Θchec en phase 1, retour immΘdiat! */
  149.   if (forbidden_url==1) {
  150.     return forbidden_url;
  151.   }
  152.   
  153.   // -------------------- PHASE 2 --------------------
  154.  
  155.   // ------------------------------------------------------
  156.   // doit-on traiter ce lien?.. vΘrifier droits de dΘplacement
  157.   meme_adresse=strfield2(adr,urladr);
  158.   if ((opt->debug>1) && (opt->log!=NULL)) {
  159.     fspc(opt->log,"debug"); 
  160.     if (meme_adresse) 
  161.       fprintf(opt->log,"Compare addresses: %s=%s"LF,adr,urladr);
  162.     else
  163.       fprintf(opt->log,"Compare addresses: %s!=%s"LF,adr,urladr);
  164.     test_flush;
  165.   }
  166.   if (meme_adresse) {  // mΩme adresse 
  167.     {  // tester interdiction de descendre
  168.       // MODIFIE : en cas de remontΘe puis de redescente, il se pouvait qu'on ne puisse pas atteindre certains fichiers
  169.       // problΦme: si un fichier est virtuellement accessible via une page mais dont le lien est sur une autre *uniquement*..
  170.       char BIGSTK tempo[HTS_URLMAXSIZE*2];
  171.       char BIGSTK tempo2[HTS_URLMAXSIZE*2];
  172.       tempo[0] = tempo2[0] = '\0';
  173.       
  174.       // note (up/down): on calcule α partir du lien primaire, ET du lien prΘcΘdent.
  175.       // ex: si on descend 2 fois on peut remonter 1 fois
  176.       
  177.       if (lienrelatif(tempo,fil,liens[liens[ptr]->premier]->fil)==0) {
  178.         if (lienrelatif(tempo2,fil,liens[ptr]->fil)==0) {
  179.           if ((opt->debug>1) && (opt->log!=NULL)) {
  180.             fspc(opt->log,"debug"); fprintf(opt->log,"build relative links to test: %s %s (with %s and %s)"LF,tempo,tempo2,liens[liens[ptr]->premier]->fil,liens[ptr]->fil);
  181.             test_flush;
  182.           }
  183.           
  184.           // si vient de primary, ne pas tester lienrelatif avec (car host "diffΘrent")
  185.           /*if (liens[liens[ptr]->premier] == 0) {   // vient de primary
  186.           }
  187.           */
  188.           
  189.           // NEW: finalement OK, sauf pour les moved repΘrΘs par link_import
  190.           // PROBLEME : annulΘ a cause d'un lien Θventuel isolΘ acceptΘ..qui entrainerait un miroir
  191.           
  192.           // (test mΩme niveau (NOUVEAU α cause de certains problΦmes de filtres non intΘgrΘs))
  193.           // NEW
  194.           if ( 
  195.             (tempo[0]  != '\0' && tempo[1]  != '\0' && strchr(tempo+1,'/') == 0)
  196.             ||
  197.             (tempo2[0] != '\0' && tempo2[1] != '\0' && strchr(tempo2+1,'/') == 0) 
  198.             ) {
  199.             if (!liens[ptr]->link_import) {   // ne rΘsulte pas d'un 'moved'
  200.               forbidden_url=0;
  201.               if ((opt->debug>1) && (opt->log!=NULL)) {
  202.                 fspc(opt->log,"debug"); fprintf(opt->log,"same level link authorized: %s%s"LF,adr,fil);
  203.                 test_flush;
  204.              }
  205.             }
  206.           }
  207.           
  208.           // down
  209.           if ( (strncmp(tempo,"../",3)) || (strncmp(tempo2,"../",3)))  {   // pas montΘe sinon ne nbous concerne pas
  210.             int test1,test2;
  211.             if (!strncmp(tempo,"../",3))
  212.               test1=0;
  213.             else
  214.               test1 = (strchr(tempo +((*tempo =='/')?1:0),'/')!=NULL);
  215.             if (!strncmp(tempo2,"../",3))
  216.               test2=0;
  217.             else
  218.               test2 = (strchr(tempo2+((*tempo2=='/')?1:0),'/')!=NULL);
  219.             if ( (test1) && (test2) ) {   // on ne peut que descendre
  220.               if ((opt->seeker & 1)==0) {  // interdiction de descendre
  221.                 forbidden_url=1;
  222.                 if ((opt->debug>1) && (opt->log!=NULL)) {
  223.                   fspc(opt->log,"debug"); fprintf(opt->log,"lower link canceled: %s%s"LF,adr,fil);
  224.                   test_flush;
  225.                 }
  226.               } else {    // autorisΘ α priori - NEW
  227.                 if (!liens[ptr]->link_import) {   // ne rΘsulte pas d'un 'moved'
  228.                   forbidden_url=0;
  229.                   if ((opt->debug>1) && (opt->log!=NULL)) {
  230.                     fspc(opt->log,"debug"); fprintf(opt->log,"lower link authorized: %s%s"LF,adr,fil);
  231.                     test_flush;
  232.                   }
  233.                 }
  234.               }
  235.             } else if ( (test1) || (test2) ) {   // on peut descendre pour accΘder au lien
  236.               if ((opt->seeker & 1)!=0) {  // on peut descendre - NEW
  237.                 if (!liens[ptr]->link_import) {   // ne rΘsulte pas d'un 'moved'
  238.                   forbidden_url=0;
  239.                   if ((opt->debug>1) && (opt->log!=NULL)) {
  240.                     fspc(opt->log,"debug"); fprintf(opt->log,"lower link authorized: %s%s"LF,adr,fil);
  241.                     test_flush;
  242.                   }
  243.                 }
  244.               }
  245.             }
  246.           }
  247.           
  248.           
  249.           // up
  250.           if ( (!strncmp(tempo,"../",3)) && (!strncmp(tempo2,"../",3)) ) {    // impossible sans monter
  251.             if ((opt->seeker & 2)==0) {  // interdiction de monter
  252.               forbidden_url=1;
  253.               if ((opt->debug>1) && (opt->log!=NULL)) {
  254.                 fspc(opt->log,"debug"); fprintf(opt->log,"upper link canceled: %s%s"LF,adr,fil);
  255.                 test_flush;
  256.               }
  257.             } else {       // autorisΘ α monter - NEW
  258.               if (!liens[ptr]->link_import) {   // ne rΘsulte pas d'un 'moved'
  259.                 forbidden_url=0;
  260.                 if ((opt->debug>1) && (opt->log!=NULL)) {
  261.                   fspc(opt->log,"debug"); fprintf(opt->log,"upper link authorized: %s%s"LF,adr,fil);
  262.                   test_flush;
  263.                 }
  264.               }
  265.             }
  266.           } else if ( (!strncmp(tempo,"../",3)) || (!strncmp(tempo2,"../",3)) ) {    // Possible en montant
  267.             if ((opt->seeker & 2)!=0) {  // autorisΘ α monter - NEW
  268.               if (!liens[ptr]->link_import) {   // ne rΘsulte pas d'un 'moved'
  269.                 forbidden_url=0;
  270.                 if ((opt->debug>1) && (opt->log!=NULL)) {
  271.                   fspc(opt->log,"debug"); fprintf(opt->log,"upper link authorized: %s%s"LF,adr,fil);
  272.                   test_flush;
  273.                 }
  274.               }
  275.             }  // sinon autorisΘ en descente
  276.           }
  277.           
  278.           
  279.         } else {
  280.           if (opt->errlog) {
  281.             fprintf(opt->errlog,"Error building relative link %s and %s"LF,fil,liens[ptr]->fil);
  282.             test_flush;
  283.           }
  284.         }
  285.       } else {
  286.         if (opt->errlog) {
  287.           fprintf(opt->errlog,"Error building relative link %s and %s"LF,fil,liens[liens[ptr]->premier]->fil);
  288.           test_flush;
  289.         }
  290.       }
  291.       
  292.     }  // tester interdiction de descendre?
  293.     
  294.     {  // tester interdiction de monter
  295.       char BIGSTK tempo[HTS_URLMAXSIZE*2];
  296.       char BIGSTK tempo2[HTS_URLMAXSIZE*2];
  297.       if (lienrelatif(tempo,fil,liens[liens[ptr]->premier]->fil)==0) {
  298.         if (lienrelatif(tempo2,fil,liens[ptr]->fil)==0) {
  299.         } else {
  300.           if (opt->errlog) { 
  301.             fprintf(opt->errlog,"Error building relative link %s and %s"LF,fil,liens[ptr]->fil);
  302.             test_flush;
  303.           }
  304.           
  305.         }
  306.       } else {
  307.         if (opt->errlog) { 
  308.           fprintf(opt->errlog,"Error building relative link %s and %s"LF,fil,liens[liens[ptr]->premier]->fil);
  309.           test_flush;
  310.         }
  311.         
  312.       }
  313.     }   // fin tester interdiction de monter
  314.     
  315.   } else {    // adresse diffΘrente, sortir?
  316.     
  317.     //if (!opt->wizard) {    // mode non wizard
  318.     // doit-on traiter ce lien?.. vΘrifier droits de sortie
  319.     switch((opt->travel & 255)) {
  320.     case 0: 
  321.       if (!opt->wizard)    // mode non wizard
  322.         forbidden_url=1; break;    // interdicton de sortir au dela de l'adresse
  323.     case 1: {              // sortie sur le mΩme dom.xxx
  324.       int i=strlen(adr)-1;
  325.       int j=strlen(urladr)-1;
  326.       while( (i>0) && (adr[i]!='.')) i--;
  327.       while( (j>0) && (urladr[j]!='.')) j--;
  328.       i--; j--;
  329.       while( (i>0) && (adr[i]!='.')) i--;
  330.       while( (j>0) && (urladr[j]!='.')) j--;
  331.       if ((i>0) && (j>0)) {
  332.         if (!strfield2(adr+i,urladr+j)) {   // !=
  333.           if (!opt->wizard) {   // mode non wizard
  334.             //printf("refused: %s\n",adr);
  335.             forbidden_url=1;  // pas mΩme domaine  
  336.             if ((opt->debug>1) && (opt->log!=NULL)) {
  337.               fspc(opt->log,"debug"); fprintf(opt->log,"foreign domain link canceled: %s%s"LF,adr,fil);
  338.               test_flush;
  339.             }
  340.           }
  341.           
  342.         } else {
  343.           if (opt->wizard) {   // mode wizard
  344.             forbidden_url=0;  // mΩme domaine  
  345.             if ((opt->debug>1) && (opt->log!=NULL)) {
  346.               fspc(opt->log,"debug"); fprintf(opt->log,"same domain link authorized: %s%s"LF,adr,fil);
  347.               test_flush;
  348.             }
  349.           }
  350.         }
  351.         
  352.       } else
  353.         forbidden_url=1;
  354.             } 
  355.       break;  
  356.     case 2: {                      // sortie sur le mΩme .xxx
  357.       int i=strlen(adr)-1;
  358.       int j=strlen(urladr)-1;
  359.       while( (i>0) && (adr[i]!='.')) i--;
  360.       while( (j>0) && (urladr[j]!='.')) j--;
  361.       if ((i>0) && (j>0)) {
  362.         if (!strfield2(adr+i,urladr+j)) {   // !-
  363.           if (!opt->wizard) {   // mode non wizard
  364.             //printf("refused: %s\n",adr);
  365.             forbidden_url=1;  // pas mΩme .xx  
  366.             if ((opt->debug>1) && (opt->log!=NULL)) {
  367.               fspc(opt->log,"debug"); fprintf(opt->log,"foreign location link canceled: %s%s"LF,adr,fil);
  368.               test_flush;
  369.             }
  370.           }
  371.         } else {
  372.           if (opt->wizard) {   // mode wizard
  373.             forbidden_url=0;  // mΩme domaine  
  374.             if ((opt->debug>1) && (opt->log!=NULL)) {
  375.               fspc(opt->log,"debug"); fprintf(opt->log,"same location link authorized: %s%s"LF,adr,fil);
  376.               test_flush;
  377.             }
  378.           }
  379.         }
  380.       } else forbidden_url=1;     
  381.             } 
  382.       break;
  383.     case 7:                 // everywhere!!
  384.       if (opt->wizard) {   // mode wizard
  385.         forbidden_url=0;
  386.         break;
  387.       }
  388.     }  // switch
  389.     
  390.     // ANCIENNE POS -- rΘcupΘrer les liens α c⌠tΘs d'un lien (nearlink)
  391.     
  392.   }  // fin test adresse identique/diffΘrente
  393.  
  394.   // -------------------- PHASE 3 --------------------
  395.  
  396.   // rΘcupΘrer les liens α c⌠tΘs d'un lien (nearlink) (nvelle pos)
  397.   if (opt->nearlink) {
  398.     if (!ishtml(fil)) {  // non html
  399.       //printf("ok %s%s\n",ad,fil);
  400.       forbidden_url=0;    // autoriser
  401.       may_set_prio_to=1+1; // set prio to 1 (parse but skip urls) if near is the winner
  402.       if ((opt->debug>1) && (opt->log!=NULL)) {
  403.         fspc(opt->log,"debug"); fprintf(opt->log,"near link authorized: %s%s"LF,adr,fil);
  404.         test_flush;
  405.       }
  406.     }
  407.   }
  408.   
  409.   // -------------------- PHASE 4 --------------------
  410.   
  411.   // ------------------------------------------------------
  412.   // Si wizard, il se peut qu'on autorise ou qu'on interdise 
  413.   // un lien spΘcial avant mΩme de tester sa position, sa hiΘrarchie etc.
  414.   // peut court-circuiter le forbidden_url prΘcΘdent
  415.   if (opt->wizard) { // le wizard entre en action..
  416.     //
  417.     int question=1;         // poser une question                            
  418.     int force_mirror=0;     // pour mirror links
  419.     int filters_answer=0;   // dΘcision prise par les filtres
  420.     char BIGSTK l[HTS_URLMAXSIZE*2];
  421.     char BIGSTK lfull[HTS_URLMAXSIZE*2];
  422.     
  423.     if (forbidden_url!=-1) question=0;  // pas de question, rΘsolu
  424.     
  425.     // former URL complΦte du lien actuel
  426.     strcpybuff(l,jump_identification(adr));
  427.     if (*fil!='/') strcatbuff(l,"/");
  428.     strcatbuff(l,fil);
  429.     // full version (http://foo:bar@www.foo.com/bar.html)
  430.     if (!link_has_authority(adr))
  431.       strcpybuff(lfull,"http://");
  432.     else
  433.       lfull[0]='\0';
  434.     strcatbuff(lfull,adr);
  435.     if (*fil!='/') strcatbuff(lfull,"/");
  436.     strcatbuff(lfull,fil);
  437.     
  438.     // tester filters (URLs autorisΘes ou interdites explicitement)
  439.     
  440.     // si lien primaire on saute le joker, on est pas lΘmur
  441.     if (ptr==0) {  // lien primaire, autoriser
  442.       question=1;    // la question sera rΘsolue automatiquement
  443.       forbidden_url=0;
  444.       may_set_prio_to=0;    // clear may-set flag
  445.     } else {
  446.       // eternal depth first
  447.       // vΘrifier rΘcursivitΘ extΘrieure
  448.       if (opt->extdepth>0) {
  449.         if ( /*question && */ (ptr>0) && (!force_mirror)) {
  450.           // well, this is kinda a hak
  451.           // we don't want to mirror EVERYTHING, and we have to decide where to stop
  452.           // there is no way yet to tag "external" links, and therefore links that are
  453.           // "weak" (authorized depth < external depth) are just not considered for external
  454.           // hack
  455.           if (liens[ptr]->depth > opt->extdepth) {
  456.             // *set_prio_to = opt->extdepth + 1;
  457.             *set_prio_to = 1 + (opt->extdepth);
  458.             may_set_prio_to=0;  // clear may-set flag
  459.             forbidden_url=0;    // autorisΘ
  460.             question=0;         // rΘsolution auto
  461.             if ((opt->debug>1) && (opt->log!=NULL)) {
  462.               if (question) {
  463.                 fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) ambiguous link accepted (external depth): link %s at %s%s"LF,l,urladr,urlfil);
  464.               } else {
  465.                 fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) forced to accept link (external depth): link %s at %s%s"LF,l,urladr,urlfil);
  466.               }
  467.               test_flush;
  468.             }
  469.             
  470.           }
  471.         }
  472.       }  
  473.       
  474.       // filters
  475.       {
  476.         int jok;
  477.         char* mdepth="";
  478.         // filters, 0=sait pas 1=ok -1=interdit
  479.         {
  480.           int jokDepth1=0,jokDepth2=0;
  481.           int jok1=0,jok2=0;
  482.           jok1  = fa_strjoker(_FILTERS,*_FILTERS_PTR,lfull,NULL,NULL,&jokDepth1);
  483.           jok2 =  fa_strjoker(_FILTERS,*_FILTERS_PTR,l,    NULL,NULL,&jokDepth2);
  484.           if (jok2 == 0) {      // #2 doesn't know
  485.             jok = jok1;        // then, use #1
  486.             mdepth = _FILTERS[jokDepth1];
  487.           } else if (jok1 == 0) { // #1 doesn't know
  488.             jok = jok2;        // then, use #2
  489.             mdepth = _FILTERS[jokDepth2];
  490.           } else if (jokDepth1 >= jokDepth2) { // #1 matching rule is "after" #2, then it is prioritary
  491.             jok = jok1;
  492.             mdepth = _FILTERS[jokDepth1];
  493.           } else {                             // #2 matching rule is "after" #1, then it is prioritary
  494.             jok = jok2;
  495.             mdepth = _FILTERS[jokDepth2];
  496.           }
  497.         }
  498.         
  499.         if (jok == 1) {   // autorisΘ
  500.           filters_answer=1;  // dΘcision prise par les filtres
  501.           question=0;    // ne pas poser de question, autorisΘ
  502.           forbidden_url=0;  // URL autorisΘe
  503.           may_set_prio_to=0;    // clear may-set flag
  504.           if ((opt->debug>1) && (opt->log!=NULL)) {
  505.             fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) explicit authorized (%s) link: link %s at %s%s"LF,mdepth,l,urladr,urlfil);
  506.             test_flush;
  507.           }
  508.         } else if (jok == -1) {  // forbidden
  509.           filters_answer=1;  // dΘcision prise par les filtres
  510.           question=0;    // ne pas poser de question:
  511.           forbidden_url=1;   // URL interdite
  512.           if ((opt->debug>1) && (opt->log!=NULL)) {
  513.             fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) explicit forbidden (%s) link: link %s at %s%s"LF,mdepth,l,urladr,urlfil);
  514.             test_flush;
  515.           }
  516.         }  // sinon on touche α rien
  517.       }
  518.     }
  519.     
  520.     // vΘrifier mode mirror links
  521.     if (question) {
  522.       if (opt->mirror_first_page) {    // mode mirror links
  523.         if (liens[ptr]->precedent==0) {  // parent=primary!
  524.           forbidden_url=0;    // autorisΘ
  525.           may_set_prio_to=0;    // clear may-set flag
  526.           question=1;         // rΘsolution auto
  527.           force_mirror=5;     // mirror (5)
  528.           if ((opt->debug>1) && (opt->log!=NULL)) {
  529.             fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) explicit mirror link: link %s at %s%s"LF,l,urladr,urlfil);
  530.             test_flush;
  531.           }
  532.         }
  533.       }
  534.     }
  535.     
  536.     // on doit poser la question.. peut on la poser?
  537.     // (oui je sais quel preuve de dΘlicatesse, merci merci)      
  538.     if ((question) && (ptr>0) && (!force_mirror)) {
  539.       if (opt->wizard==2) {    // Θliminer tous les liens non rΘpertoriΘs comme autorisΘs (ou inconnus)
  540.         question=0;
  541.         forbidden_url=1;
  542.         if ((opt->debug>1) && (opt->log!=NULL)) {
  543.           fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) ambiguous forbidden link: link %s at %s%s"LF,l,urladr,urlfil);
  544.           test_flush;
  545.         }
  546.       }
  547.     }
  548.     
  549.     // vΘrifier robots.txt
  550.     if (opt->robots) {
  551.       int r = checkrobots(_ROBOTS,adr,fil);
  552.       if (r == -1) {    // interdiction
  553. #if DEBUG_ROBOTS
  554.         printf("robots.txt forbidden: %s%s\n",adr,fil);
  555. #endif
  556.         // question rΘsolue, par les filtres, et mode robot non strict
  557.         if ((!question) && (filters_answer) && (opt->robots == 1) && (forbidden_url!=1)) {
  558.           r=0;    // annuler interdiction des robots
  559.           if (!forbidden_url) {
  560.             if ((opt->debug>1) && (opt->log!=NULL)) {
  561.               fspc(opt->log,"debug"); fprintf(opt->log,"Warning link followed against robots.txt: link %s at %s%s"LF,l,adr,fil);
  562.               test_flush;
  563.             }
  564.           }
  565.         }
  566.         if (r == -1) {    // interdire
  567.           forbidden_url=1;
  568.           question=0;
  569.           if ((opt->debug>1) && (opt->log!=NULL)) {
  570.             fspc(opt->log,"debug"); fprintf(opt->log,"(robots.txt) forbidden link: link %s at %s%s"LF,l,adr,fil);
  571.             test_flush;
  572.           }
  573.         }
  574.       }
  575.     }
  576.     
  577.     if (!question) {
  578.       if ((opt->debug>1) && (opt->log!=NULL)) {
  579.         if (!forbidden_url) {
  580.           fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) shared foreign domain link: link %s at %s%s"LF,l,urladr,urlfil);
  581.         } else {
  582.           fspc(opt->log,"debug"); fprintf(opt->log,"(wizard) cancelled foreign domain link: link %s at %s%s"LF,l,urladr,urlfil);
  583.         }
  584.         test_flush;
  585.       }
  586. #if BDEBUG==3
  587.       printf("at %s in %s, wizard says: url %s ",urladr,urlfil,l);
  588.       if (forbidden_url) printf("cancelled"); else printf(">SHARED<");
  589.       printf("\n");
  590. #endif 
  591.     }
  592.  
  593.     /* en cas de question, ou lien primaire (enregistrer autorisations) */
  594.     if (question || (ptr==0)) {
  595. #if HTS_ANALYSTE
  596.       char* s;
  597. #else
  598.       char s[4];
  599. #endif
  600.       int n=0;
  601.       
  602.       // si primaire (plus bas) alors ...
  603.       if ((ptr!=0) && (force_mirror==0)) {
  604.         HTS_REQUEST_START;
  605.         HT_PRINT("\n");
  606.         HT_PRINT("At "); HT_PRINT(urladr); HT_PRINT(", there is a link ("); HT_PRINT(adr); HT_PRINT("/"); HT_PRINT(fil); HT_PRINT(") which goes outside the address."LF);
  607.         HT_PRINT("What should I do? (press a key + enter)"LF LF);
  608.         HT_PRINT("* Ignore all further links" LF);
  609.         HT_PRINT("0 Ignore this link (default if empty entry)"LF);
  610.         HT_PRINT("1 Ignore directory and lower structures"LF);
  611.         HT_PRINT("2 Ignore all domain"LF);
  612.         //HT_PRINT("3 (Ignore location, not implemented)\n");
  613.         HT_PRINT(LF);
  614.         HT_PRINT("4 Get only this page/link"LF);
  615.         HT_PRINT("5 Mirror this link (useful)"LF);
  616.         HT_PRINT("6 Mirror links located in the same domain"LF);
  617.         HT_PRINT(LF);
  618. //#if HTS_ANALYSTE!=2
  619. //HT_PRINT("! View extract of html code where the link is located"LF);
  620. //#endif
  621.         HTS_REQUEST_END;
  622. #if HTS_ANALYSTE
  623.           {
  624.             char BIGSTK tempo[HTS_URLMAXSIZE*2];
  625.             tempo[0]='\0';
  626.             strcatbuff(tempo,adr);
  627.             strcatbuff(tempo,"/");
  628.             strcatbuff(tempo,fil);
  629.             s=hts_htmlcheck_query3(tempo);
  630.           }
  631. #else
  632.         do {
  633.           io_flush; linput(stdin,s,2);
  634. #endif
  635.           if (strnotempty(s)==0)  // entrΘe
  636.             n=0;
  637.           else if (isdigit((unsigned char)*s))
  638.             sscanf(s,"%d",&n);
  639.           else {
  640.             switch(*s) {
  641.             case '*': n=-1; break;
  642.             case '!': n=-999; {
  643.               /*char *a;
  644.               int i;                                    
  645.               a=copie_de_adr-128;
  646.               if (a<r.adr) a=r.adr;
  647.               for(i=0;i<256;i++) {
  648.                 if (a==copie_de_adr) printf("\nHERE:\n");
  649.                 printf("%c",*a++);
  650.               }
  651.               printf("\n\n");
  652.               */
  653.                       }
  654.               break;
  655.             default: n=-999; printf("What did you say?\n"); break;
  656.               
  657.             } 
  658.           }
  659. #if HTS_ANALYSTE
  660. #else
  661.         } while(n==-999);
  662. #endif
  663.         io_flush;
  664.       } else {   // lien primaire: autoriser rΘpertoire entier       
  665.         if (!force_mirror) {
  666.           if ((opt->seeker & 1)==0) {  // interdiction de descendre
  667.             n=7;
  668.           } else {
  669.             n=5;   // autoriser miroir rΘpertoires descendants (lien primaire)
  670.           }
  671.         } else   // forcer valeur (sub-wizard)
  672.           n=force_mirror;
  673.       }
  674.       
  675.       /* sanity check - reallocate filters HERE */
  676.       if ((*_FILTERS_PTR) + 1 >= opt->maxfilter) {
  677.         opt->maxfilter += HTS_FILTERSINC;
  678.         if (filters_init(&_FILTERS, opt->maxfilter, HTS_FILTERSINC) == 0) {
  679.           printf("PANIC! : Too many filters : >%d [%d]\n", (*_FILTERS_PTR),__LINE__);
  680.           fflush(stdout);
  681.           if (opt->errlog) {
  682.             fprintf(opt->errlog,LF"Too many filters, giving up..(>%d)"LF, (*_FILTERS_PTR) );
  683.             fprintf(opt->errlog,"To avoid that: use #F option for more filters (example: -#F5000)"LF);
  684.             test_flush;
  685.           }
  686.           assertf("too many filters - giving up" == NULL);    // wild..
  687.         }
  688.       }
  689.  
  690.       // here we have enough room for a new filter if necessary
  691.       switch(n) {
  692.       case -1: // sauter tout le reste
  693.         forbidden_url=1;
  694.         opt->wizard=2;    // sauter tout le reste
  695.         break;
  696.       case 0:    // interdire les mΩmes liens: adr/fil
  697.         forbidden_url=1; 
  698.         HT_INSERT_FILTERS0;    // insΘrer en 0
  699.         strcpybuff(_FILTERS[0],"-");
  700.         strcatbuff(_FILTERS[0],jump_identification(adr));
  701.         if (*fil!='/') strcatbuff(_FILTERS[0],"/");
  702.         strcatbuff(_FILTERS[0],fil);
  703.         break;
  704.         
  705.       case 1: // Θliminer rΘpertoire entier et sous rΘp: adr/path/ *
  706.         forbidden_url=1;
  707.         {
  708.           int i=strlen(fil)-1;
  709.           while((fil[i]!='/') && (i>0)) i--;
  710.           if (fil[i]=='/') {
  711.             HT_INSERT_FILTERS0;    // insΘrer en 0
  712.             strcpybuff(_FILTERS[0],"-");
  713.             strcatbuff(_FILTERS[0],jump_identification(adr));
  714.             if (*fil!='/') strcatbuff(_FILTERS[0],"/");
  715.             strncatbuff(_FILTERS[0] ,fil,i);
  716.             if (_FILTERS[0][strlen(_FILTERS[0])-1]!='/') 
  717.               strcatbuff(_FILTERS[0],"/");
  718.             strcatbuff(_FILTERS[0],"*");
  719.           }
  720.         }            
  721.         
  722.         // ** ...
  723.         break;
  724.         
  725.       case 2:    // adresse adr*
  726.         forbidden_url=1;
  727.         HT_INSERT_FILTERS0;    // insΘrer en 0                                
  728.         strcpybuff(_FILTERS[0],"-");
  729.         strcatbuff(_FILTERS[0],jump_identification(adr));
  730.         strcatbuff(_FILTERS[0],"*");
  731.         break;
  732.         
  733.       case 3: // ** A FAIRE
  734.         forbidden_url=1;
  735.         /*
  736.         {
  737.         int i=strlen(adr)-1;
  738.         while((adr[i]!='/') && (i>0)) i--;
  739.         if (i>0) {
  740.         
  741.           }
  742.           
  743.       }*/
  744.         
  745.         break;
  746.         //
  747.       case 4:    // same link
  748.         // PAS BESOIN!!
  749.         /*HT_INSERT_FILTERS0;    // insΘrer en 0                                
  750.         strcpybuff(_FILTERS[0],"+");
  751.         strcatbuff(_FILTERS[0],adr);
  752.         if (*fil!='/') strcatbuff(_FILTERS[0],"/");
  753.         strcatbuff(_FILTERS[0],fil);*/
  754.         
  755.         
  756.         // Θtant donnΘ le renversement wizard/primary filter (les primary autorisent up/down ET interdisent)
  757.         // il faut Θviter d'un lien isolΘ effectue un miroir total..
  758.         
  759.         *set_prio_to = 0+1;    // niveau de rΘcursion=0 (pas de miroir)
  760.         
  761.         break;
  762.         
  763.       case 5:    // autoriser rΘpertoire entier et fils
  764.         if ((opt->seeker & 2)==0) {  // interdiction de monter
  765.           int i=strlen(fil)-1;
  766.           while((fil[i]!='/') && (i>0)) i--;
  767.           if (fil[i]=='/') {
  768.             HT_INSERT_FILTERS0;    // insΘrer en 0                                
  769.             strcpybuff(_FILTERS[0],"+");
  770.             strcatbuff(_FILTERS[0],jump_identification(adr));
  771.             if (*fil!='/') strcatbuff(_FILTERS[0],"/");
  772.             strncatbuff(_FILTERS[0],fil,i+1);
  773.             strcatbuff(_FILTERS[0],"*");
  774.           }
  775.         } else {    // autoriser domaine alors!!
  776.           HT_INSERT_FILTERS0;    // insΘrer en 0                                strcpybuff(filters[filptr],"+");
  777.           strcpybuff(_FILTERS[0],"+");
  778.           strcatbuff(_FILTERS[0],jump_identification(adr));
  779.           strcatbuff(_FILTERS[0],"*");
  780.         }
  781.         break;
  782.         
  783.       case 6:    // same domain
  784.         HT_INSERT_FILTERS0;    // insΘrer en 0                                strcpybuff(filters[filptr],"+");
  785.         strcpybuff(_FILTERS[0],"+");
  786.         strcatbuff(_FILTERS[0],jump_identification(adr));
  787.         strcatbuff(_FILTERS[0],"*");
  788.         break;
  789.         //
  790.       case 7:    // autoriser ce rΘpertoire
  791.         {
  792.           int i=strlen(fil)-1;
  793.           while((fil[i]!='/') && (i>0)) i--;
  794.           if (fil[i]=='/') {
  795.             HT_INSERT_FILTERS0;    // insΘrer en 0                                
  796.             strcpybuff(_FILTERS[0],"+");
  797.             strcatbuff(_FILTERS[0],jump_identification(adr));
  798.             if (*fil!='/') strcatbuff(_FILTERS[0],"/");
  799.             strncatbuff(_FILTERS[0],fil,i+1);
  800.             strcatbuff(_FILTERS[0],"*[file]");
  801.           }
  802.         }
  803.         
  804.         break;
  805.         
  806.       case 50:    // on fait rien
  807.         break;
  808.       }  // switch 
  809.                               
  810.     }  // test du wizard sur l'url
  811.   }  // fin du test wizard..
  812.  
  813.   // -------------------- PHASE 5 --------------------
  814.  
  815.   // lien non autorisΘ, peut-on juste le tester?
  816.   if (just_test_it) {
  817.     if (forbidden_url==1) {
  818.       if (opt->travel&256) {    // tester tout de mΩme
  819.         if (strfield(adr,"ftp://")==0) {    // PAS ftp!
  820.           forbidden_url=1;    // oui oui toujours interdit (note: sert α rien car ==1 mais c pour comprendre)
  821.           *just_test_it=1;     // mais on teste
  822.           if ((opt->debug>1) && (opt->log!=NULL)) {
  823.             fspc(opt->log,"debug"); fprintf(opt->log,"Testing link %s%s"LF,adr,fil);
  824.           }
  825.         }
  826.       }
  827.     }
  828.     //adr[0]='\0';  // cancel
  829.   }
  830.  
  831.   // -------------------- PHASE 6 --------------------
  832. #if HTS_ANALYSTE
  833.   {
  834.     int test_url=hts_htmlcheck_check(adr,fil,forbidden_url);
  835.     if (test_url!=-1) {
  836.       forbidden_url=test_url;
  837.       may_set_prio_to=0;    // clear may-set flag
  838.     }
  839.   }
  840. #endif
  841.  
  842.   // -------------------- FINAL PHASE --------------------
  843.   // Test if the "Near" test won
  844.   if (may_set_prio_to && forbidden_url == 0) {
  845.     *set_prio_to = may_set_prio_to;
  846.   }
  847.  
  848.   return forbidden_url;
  849. }
  850.  
  851. // tester taille
  852. int hts_testlinksize(httrackp* opt,
  853.                      char* adr,char* fil,
  854.                      LLint size) {
  855.   int jok=0;
  856.   if (size>=0) {
  857.     char BIGSTK l[HTS_URLMAXSIZE*2];
  858.     char BIGSTK lfull[HTS_URLMAXSIZE*2];
  859.     if (size>=0) {
  860.       LLint sz=size;
  861.       int size_flag=0;
  862.       
  863.       // former URL complΦte du lien actuel
  864.       strcpybuff(l,jump_identification(adr));
  865.       if (*fil!='/') strcatbuff(l,"/");
  866.       strcatbuff(l,fil);
  867.       //
  868.       if (!link_has_authority(adr))
  869.         strcpybuff(lfull,"http://");
  870.       else
  871.         lfull[0]='\0';
  872.       strcatbuff(lfull,adr);
  873.       if (*fil!='/') strcatbuff(l,"/");
  874.       strcatbuff(lfull,fil);
  875.       
  876.       // tester filtres (taille)
  877.       // jok = fa_strjoker(opt->filters.filters,*opt->filters.filptr,l,&sz,&size_flag,NULL);
  878.  
  879.       // filters, 0=sait pas 1=ok -1=interdit
  880.       {
  881.         int jokDepth1=0,jokDepth2=0;
  882.         int jok1=0,jok2=0;
  883.         LLint sz1=size,sz2=size;
  884.         int size_flag1=0,size_flag2=0;
  885.         jok1  = fa_strjoker(*opt->filters.filters,*opt->filters.filptr,lfull,&sz1,&size_flag1,&jokDepth1);
  886.         jok2 =  fa_strjoker(*opt->filters.filters,*opt->filters.filptr,l,    &sz2,&size_flag2,&jokDepth2);
  887.         if (jok2 == 0) {      // #2 doesn't know
  888.           jok = jok1;        // then, use #1
  889.           sz = sz1;
  890.           size_flag = size_flag1;
  891.         } else if (jok1 == 0) {  // #1 doesn't know
  892.           jok = jok2;        // then, use #2
  893.           sz = sz2;
  894.           size_flag = size_flag2;
  895.         } else if (jokDepth1 >= jokDepth2) { // #1 matching rule is "after" #2, then it is prioritary
  896.           jok = jok1;
  897.           sz = sz1;
  898.           size_flag = size_flag1;
  899.         } else {                              // #2 matching rule is "after" #1, then it is prioritary
  900.           jok = jok2;
  901.           sz = sz2;
  902.           size_flag = size_flag2;
  903.         } 
  904.       }
  905.       
  906.  
  907.       // log
  908.       if (jok==1) {
  909.         if ((opt->debug>1) && (opt->log!=NULL)) {
  910.           fspc(opt->log,"debug"); fprintf(opt->log,"File confirmed (size test): %s%s ("LLintP")"LF,adr,fil,(LLint)(size));
  911.         }
  912.       } else if (jok==-1) {
  913.         if (size_flag) {        /* interdit α cause de la taille */
  914.           if ((opt->debug>1) && (opt->log!=NULL)) {
  915.             fspc(opt->log,"debug"); fprintf(opt->log,"File cancelled due to its size: %s%s ("LLintP", limit: "LLintP")"LF,adr,fil,(LLint)(size),(LLint)(sz));
  916.           }
  917.         } else {
  918.           jok=1;
  919.         }
  920.       }
  921.     }
  922.   }
  923.   return jok;
  924. }
  925.  
  926.  
  927.  
  928. #undef test_flush
  929. #undef urladr
  930. #undef urlfil
  931.  
  932. #undef HT_INSERT_FILTERS0
  933.  
  934.